"""
增强服务模块 - 新增核心功能
"""

import asyncio
from typing import Dict, List, Optional
from datetime import datetime
import json
from dataclasses import dataclass
from bilibili_api import video, user, search, bangumi, comment
from .bilibili_service import BilibiliService


@dataclass
class UserProfile:
    """用户学习画像"""
    uid: str
    interests: List[str]  # 兴趣领域
    level: str  # 学习水平
    history: List[str]  # 观看历史
    preferences: Dict  # 偏好设置
    learning_goals: List[str]  # 学习目标
    study_time: int  # 总学习时间(分钟)


@dataclass
class CourseSeries:
    """系列课程信息"""
    series_id: str
    title: str
    description: str
    videos: List[Dict]  # 视频列表
    difficulty: str  # 难度等级
    estimated_time: int  # 预计学习时间(分钟)
    prerequisites: List[str]  # 前置知识
    learning_objectives: List[str]  # 学习目标


@dataclass
class KnowledgeNode:
    """知识图谱节点"""
    concept_id: str
    name: str
    description: str
    difficulty: int  # 1-5级难度
    prerequisites: List[str]  # 前置知识点
    related_concepts: List[str]  # 相关知识点
    video_examples: List[str]  # 相关视频BV号
    mastery_level: int  # 掌握程度 0-100


class EnhancedBilibiliService(BilibiliService):
    """增强版B站服务"""

    def __init__(self):
        super().__init__()
        self.user_profiles = {}  # 简单的内存存储，实际应使用数据库

    async def analyze_series_course(self, uid: int, limit: int = 20) -> Dict:
        """分析UP主的系列课程"""
        try:
            # 获取UP主信息
            u = user.User(uid)
            info = await u.get_info()

            # 获取用户所有视频
            videos = []
            offset = ""
            page = 1

            while page <= 5:  # 限制获取页数，避免过多请求
                page_data = await u.get_dynamics_new(offset)

                if not page_data.get('items'):
                    break

                for item in page_data['items']:
                    if item.get('card_type') == 'video':
                        # 提取视频信息
                        video_data = item.get('card', {})
                        if video_data.get('bvid'):
                            videos.append({
                                'bvid': video_data['bvid'],
                                'title': video_data['title'],
                                'desc': video_data['desc'],
                                'duration': video_data['duration'],
                                'view': video_data.get('stat', {}).get('view', 0),
                                'like': video_data.get('stat', {}).get('like', 0)
                            })

                offset = page_data.get('offset', '')
                page += 1

                if not offset:
                    break

            # 按播放量排序，识别可能的系列课程
            videos_sorted = sorted(videos, key=lambda x: x['view'], reverse=True)

            # 简单的系列课程识别（基于标题相似性）
            series_groups = self._identify_series_courses(videos_sorted)

            return {
                'success': True,
                'data': {
                    'uploader_info': {
                        'uid': uid,
                        'name': info.get('name', ''),
                        'fans': info.get('fans', 0),
                        'description': info.get('sign', '')
                    },
                    'total_videos': len(videos),
                    'series_courses': series_groups,
                    'top_videos': videos_sorted[:10]
                }
            }

        except Exception as e:
            return {
                'success': False,
                'error': f'分析系列课程失败: {str(e)}'
            }

    def _identify_series_courses(self, videos: List[Dict]) -> List[Dict]:
        """识别系列课程"""
        series_groups = []
        processed_videos = set()

        for video in videos:
            if video['bvid'] in processed_videos:
                continue

            # 寻找相似标题的视频
            similar_videos = []
            title_prefix = self._extract_series_prefix(video['title'])

            if title_prefix:
                for other_video in videos:
                    if (other_video['bvid'] != video['bvid'] and
                        other_video['bvid'] not in processed_videos and
                        title_prefix in other_video['title']):
                        similar_videos.append(other_video)
                        processed_videos.add(other_video['bvid'])

            if similar_videos:
                series_videos = [video] + similar_videos
                series_groups.append({
                    'title': title_prefix,
                    'video_count': len(series_videos),
                    'total_views': sum(v['view'] for v in series_videos),
                    'total_likes': sum(v['like'] for v in series_videos),
                    'videos': sorted(series_videos, key=lambda x: x['title'])
                })
                processed_videos.add(video['bvid'])

        return series_groups

    def _extract_series_prefix(self, title: str) -> str:
        """提取系列课程标题前缀"""
        # 常见的系列课程模式
        patterns = [
            r'第.*讲',
            r'.*第.*期',
            r'.*第.*节',
            r'.*第.*章',
            r'\d+\..*',  # 数字开头的
            r'（.*）第.*',
        ]

        import re
        for pattern in patterns:
            match = re.search(pattern, title)
            if match:
                return title[:match.start()].strip()

        return ""

    async def get_related_recommendations(self, bvid: str, count: int = 10) -> Dict:
        """获取相关推荐视频"""
        try:
            # 获取原视频信息
            v = video.Video(bvid=bvid)
            info = await v.get_info()

            # 提取标签和关键词
            tags = info.get('title', '') + ' ' + info.get('desc', '')

            # 使用搜索API找相关视频
            search_results = []
            for keyword in self._extract_keywords(tags):
                results = await search.search_by_type(
                    keyword,
                    search_type=search.SearchObjectType.VIDEO,
                    order_type=search.OrderVideo.SCORES,
                    page=1
                )

                for result in results.get('result', [])[:3]:  # 每个关键词取前3个
                    if result.get('bvid') != bvid and result.get('bvid') not in [r.get('bvid') for r in search_results]:
                        # 清理和标准化视频数据
                        cleaned_result = self._clean_video_data(result)
                        search_results.append(cleaned_result)

                if len(search_results) >= count:
                    break

            return {
                'success': True,
                'data': {
                    'recommendations': search_results[:count],
                    'original_video_tags': self._extract_keywords(tags)
                }
            }

        except Exception as e:
            return {
                'success': False,
                'error': f'获取推荐失败: {str(e)}'
            }

    def _extract_keywords(self, text: str) -> List[str]:
        """提取关键词"""
        # 简单的关键词提取
        import re

        # 移除特殊字符
        text = re.sub(r'[^\w\s\u4e00-\u9fff]', ' ', text)

        # 分割并过滤
        words = text.split()

        # 过滤掉太短的词
        keywords = [word for word in words if len(word) >= 2]

        # 限制数量
        return keywords[:5]

    def _clean_video_data(self, video_data: Dict) -> Dict:
        """清理和标准化视频数据"""
        import re
        from html import unescape

        def clean_text(text):
            """清理文本中的HTML标签和特殊字符"""
            if not text:
                return ""

            # HTML解码
            text = unescape(str(text))

            # 移除HTML标签
            text = re.sub(r'<[^>]+>', '', text)

            # 移除多余的空白字符
            text = re.sub(r'\s+', ' ', text).strip()

            # 移除特殊格式标记
            text = re.sub(r'<em[^>]*>|</em>', '', text)  # 移除em标签
            text = re.sub(r'<strong[^>]*>|</strong>', '', text)  # 移除strong标签

            return text

        # 创建清理后的数据副本
        cleaned = {
            'bvid': video_data.get('bvid', ''),
            'title': clean_text(video_data.get('title', '')),
            'author': clean_text(video_data.get('author', '')) or clean_text(video_data.get('uname', '')) or '未知UP主',
            'desc': clean_text(video_data.get('description', '')) or clean_text(video_data.get('desc', '')),
            'pic': video_data.get('pic', ''),
            'duration': video_data.get('duration', 0),
            'play': video_data.get('play', 0) or video_data.get('view', 0),
            'like': video_data.get('like', 0) or video_data.get('likes', 0),
            'coins': video_data.get('coins', 0) or video_data.get('coin', 0),
            'danmaku': video_data.get('danmaku', 0) or video_data.get('video_review', 0),
            'review': video_data.get('review', 0) or video_data.get('reply', 0),
            'pubdate': video_data.get('pubdate', 0),
            'typeid': video_data.get('typeid', 0)
        }

        # 确保必要字段存在
        if not cleaned['title']:
            cleaned['title'] = '无标题'

        return cleaned

    async def advanced_search(self, params: Dict, page: int = 1) -> Dict:
        """高级搜索功能"""
        try:
            keyword = params.get('keyword', '')

            # 转换搜索参数
            from bilibili_api import search

            # 设置排序方式
            order_type = search.OrderVideo.SCORES  # 默认按综合评分
            if params.get('order') == 'play':
                order_type = search.OrderVideo.PLAY
            elif params.get('order') == 'upload':
                order_type = search.OrderVideo.PUBDATE

            # 设置时间范围
            time_range = 0  # 默认不限
            if params.get('time_range') == 'week':
                time_range = 7
            elif params.get('time_range') == 'month':
                time_range = 30
            elif params.get('time_range') == 'year':
                time_range = 365

            # 执行搜索
            results = await search.search_by_type(
                keyword,
                search_type=search.SearchObjectType.VIDEO,
                order_type=order_type,
                page=page
            )

            # 过滤和处理结果
            filtered_results = []
            for video in results.get('result', []):
                # 时长过滤
                duration = video.get('duration', 0)
                if params.get('duration') == 'short' and duration > 600:  # 10分钟
                    continue
                elif params.get('duration') == 'medium' and (duration < 600 or duration > 1800):  # 10-30分钟
                    continue
                elif params.get('duration') == 'long' and duration < 1800:  # 30分钟以上
                    continue

                filtered_results.append(video)

            return {
                'success': True,
                'data': {
                    'results': filtered_results,
                    'total': len(filtered_results),
                    'page': page,
                    'params': params
                }
            }

        except Exception as e:
            return {
                'success': False,
                'error': f'高级搜索失败: {str(e)}'
            }

    async def create_learning_path(self, topic: str, user_level: str = 'beginner') -> Dict:
        """创建学习路径"""
        try:
            # 搜索相关视频
            search_results = await search.search_by_type(
                topic,
                search_type=search.SearchObjectType.VIDEO,
                order_type=search.OrderVideo.SCORES,
                time_range=30,  # 10-30分钟的视频
                page=1
            )

            videos = search_results.get('result', [])[:20]

            # 根据学习水平组织内容
            if user_level == 'beginner':
                # 初学者：先看基础概念，再看实际应用
                organized_videos = self._organize_for_beginners(videos, topic)
            elif user_level == 'intermediate':
                # 中级：理论与实践结合
                organized_videos = self._organize_for_intermediate(videos, topic)
            else:
                # 高级：深度专题研究
                organized_videos = self._organize_for_advanced(videos, topic)

            # 计算学习时间
            total_time = sum(video.get('duration', 0) for video in videos) // 60  # 转换为分钟

            return {
                'success': True,
                'data': {
                    'topic': topic,
                    'user_level': user_level,
                    'total_videos': len(videos),
                    'estimated_time_minutes': total_time,
                    'learning_stages': organized_videos,
                    'learning_objectives': self._generate_learning_objectives(topic, user_level)
                }
            }

        except Exception as e:
            return {
                'success': False,
                'error': f'创建学习路径失败: {str(e)}'
            }

    def _organize_for_beginners(self, videos: List[Dict], topic: str) -> List[Dict]:
        """为初学者组织学习内容"""
        stages = [
            {
                'stage': '基础概念',
                'description': f'了解{topic}的基本概念和核心原理',
                'videos': []
            },
            {
                'stage': '入门实践',
                'description': f'{topic}的简单应用和实际操作',
                'videos': []
            },
            {
                'stage': '案例分析',
                'description': f'通过实际案例深入理解{topic}',
                'videos': []
            }
        ]

        # 简单的视频分类逻辑
        for video in videos:
            title = video.get('title', '').lower()
            desc = video.get('description', '').lower()

            if any(keyword in title + desc for keyword in ['入门', '基础', '概念', '介绍', '什么是']):
                stages[0]['videos'].append(video)
            elif any(keyword in title + desc for keyword in ['实践', '操作', '应用', '教程', '如何']):
                stages[1]['videos'].append(video)
            else:
                stages[2]['videos'].append(video)

        return [stage for stage in stages if stage['videos']]

    def _organize_for_intermediate(self, videos: List[Dict], topic: str) -> List[Dict]:
        """为中级学习者组织内容"""
        stages = [
            {
                'stage': '理论深化',
                'description': f'深入理解{topic}的理论基础',
                'videos': []
            },
            {
                'stage': '实践应用',
                'description': f'{topic}的实际应用和项目实践',
                'videos': []
            },
            {
                'stage': '问题解决',
                'description': f'常见问题分析和解决方案',
                'videos': []
            }
        ]

        # 类似的分类逻辑...
        return stages

    def _organize_for_advanced(self, videos: List[Dict], topic: str) -> List[Dict]:
        """为高级学习者组织内容"""
        stages = [
            {
                'stage': '专题研究',
                'description': f'{topic}的深度专题研究',
                'videos': []
            },
            {
                'stage': '前沿发展',
                'description': f'{topic}的最新发展和趋势',
                'videos': []
            }
        ]

        # 类似的分类逻辑...
        return stages

    def _generate_learning_objectives(self, topic: str, level: str) -> List[str]:
        """生成学习目标"""
        objectives = {
            'beginner': [
                f'理解{topic}的基本概念和定义',
                f'掌握{topic}的核心原理',
                f'能够识别{topic}的基本应用场景',
                f'完成{topic}的入门实践'
            ],
            'intermediate': [
                f'深入理解{topic}的理论基础',
                f'掌握{topic}的实际应用技巧',
                f'能够分析和解决{topic}相关问题',
                f'独立完成{topic}相关项目'
            ],
            'advanced': [
                f'精通{topic}的高级概念和理论',
                f'能够进行{topic}的创新应用',
                f'掌握{topic}的前沿发展动态',
                f'具备{topic}的研究和开发能力'
            ]
        }

        return objectives.get(level, objectives['beginner'])


class LearningAnalyticsService:
    """学习分析服务"""

    def __init__(self):
        self.learning_records = {}  # 学习记录存储

    async def track_learning_progress(self, user_id: str, video_bvid: str, progress_data: Dict) -> Dict:
        """跟踪学习进度"""
        try:
            if user_id not in self.learning_records:
                self.learning_records[user_id] = {
                    'videos_completed': [],
                    'total_study_time': 0,
                    'skills_mastered': [],
                    'learning_streak': 0,
                    'last_study_date': None
                }

            user_record = self.learning_records[user_id]

            # 更新学习记录
            if video_bvid not in user_record['videos_completed']:
                user_record['videos_completed'].append(video_bvid)

            user_record['total_study_time'] += progress_data.get('watch_time', 0)
            user_record['last_study_date'] = datetime.now().isoformat()

            # 计算学习连续天数
            user_record['learning_streak'] = self._calculate_learning_streak(user_record)

            return {
                'success': True,
                'data': {
                    'videos_completed': len(user_record['videos_completed']),
                    'total_study_time': user_record['total_study_time'],
                    'learning_streak': user_record['learning_streak'],
                    'progress_percentage': min(100, len(user_record['videos_completed']) * 10)
                }
            }

        except Exception as e:
            return {
                'success': False,
                'error': f'跟踪学习进度失败: {str(e)}'
            }

    def _calculate_learning_streak(self, user_record: Dict) -> int:
        """计算学习连续天数"""
        # 简化实现，实际应该基于历史日期计算
        return 1

    async def generate_knowledge_map(self, topic: str, videos: List[Dict]) -> Dict:
        """生成知识图谱"""
        try:
            # 基于视频标题和描述构建知识图谱
            concepts = []
            relationships = []

            for video in videos:
                # 提取概念
                title = video.get('title', '')
                desc = video.get('description', '')

                # 简单的概念提取
                concepts.extend(self._extract_concepts_from_text(title))
                concepts.extend(self._extract_concepts_from_text(desc))

            # 去重
            unique_concepts = list(set(concepts))

            # 构建节点
            nodes = []
            for i, concept in enumerate(unique_concepts[:20]):  # 限制节点数量
                nodes.append({
                    'id': f'concept_{i}',
                    'name': concept,
                    'description': concept,
                    'difficulty': min(5, len(concept) // 3 + 1),
                    'video_count': 1
                })

            # 构建关系（简化实现）
            edges = []
            for i in range(len(nodes) - 1):
                edges.append({
                    'source': nodes[i]['id'],
                    'target': nodes[i + 1]['id'],
                    'relationship': '相关'
                })

            return {
                'success': True,
                'data': {
                    'topic': topic,
                    'nodes': nodes,
                    'edges': edges,
                    'total_concepts': len(nodes)
                }
            }

        except Exception as e:
            return {
                'success': False,
                'error': f'生成知识图谱失败: {str(e)}'
            }

    def _extract_concepts_from_text(self, text: str) -> List[str]:
        """从文本中提取概念"""
        import re

        # 简单的概念提取：名词和术语
        # 这里使用正则表达式匹配可能的术语
        patterns = [
            r'[A-Za-z]+[A-Za-z0-9]*',  # 英文术语
            r'[\u4e00-\u9fff]{2,}',    # 中文词组
        ]

        concepts = []
        for pattern in patterns:
            matches = re.findall(pattern, text)
            concepts.extend(matches)

        # 过滤和清理
        filtered_concepts = []
        for concept in concepts:
            if len(concept) >= 2 and concept not in ['的', '是', '在', '有', '和', '与', '了']:
                filtered_concepts.append(concept)

        return filtered_concepts[:10]  # 限制数量


class EnhancedAIService:
    """增强AI服务"""

    def __init__(self):
        from .ai_service import AIService
        self.base_ai_service = AIService()

    async def generate_personalized_learning_advice(self, user_profile: UserProfile, video_analysis: Dict) -> Dict:
        """生成个性化学习建议"""
        try:
            # 构建个性化提示词
            prompt = f"""
            基于以下用户画像和视频分析结果，生成个性化学习建议：

            用户画像：
            - 学习水平：{user_profile.level}
            - 兴趣领域：{', '.join(user_profile.interests)}
            - 学习目标：{', '.join(user_profile.learning_goals)}
            - 已学习时间：{user_profile.study_time}分钟

            视频分析结果：
            {json.dumps(video_analysis, ensure_ascii=False, indent=2)}

            请提供：
            1. 针对该用户的学习建议（3-5条）
            2. 推荐的下一步学习内容
            3. 技能提升建议
            4. 学习方法优化建议

            请以JSON格式返回，包含advice, next_steps, skill_improvements, study_tips四个字段。
            """

            # 调用AI服务
            response = self.base_ai_service.client.chat.completions.create(
                model=self.base_ai_service.model,
                messages=[
                    {
                        "role": "system",
                        "content": "你是一个专业的学习顾问，擅长根据用户情况提供个性化学习建议。"
                    },
                    {
                        "role": "user",
                        "content": prompt
                    }
                ],
                temperature=0.7,
                max_tokens=2000
            )

            advice_text = response.choices[0].message.content

            # 尝试解析JSON响应
            try:
                advice_data = json.loads(advice_text)
            except:
                # 如果解析失败，使用默认格式
                advice_data = {
                    "advice": [advice_text],
                    "next_steps": ["继续深入学习相关内容"],
                    "skill_improvements": ["提升实践能力"],
                    "study_tips": ["多做练习，理论结合实践"]
                }

            return {
                'success': True,
                'data': advice_data
            }

        except Exception as e:
            return {
                'success': False,
                'error': f'生成个性化建议失败: {str(e)}'
            }